import pandas as pd
import numpy as np
from openpyxl import load_workbook

def preprocess_male_data(file_path):
    """
    处理男胎检测数据
    """
    # 1. 读取数据（保留所有列）
    male_data = pd.read_excel('附件.xlsx', sheet_name='男胎检测数据', dtype=str)
    print("原始数据形状:", male_data.shape)
    
    # 2. 重命名需要处理的列（其他列保持不变）
    male_data = male_data.rename(columns={
        '检测孕周': '检测孕周(处理后)',
        '孕妇BMI': '孕妇BMI（处理后）',
        'Y染色体浓度': 'Y染色体浓度（处理后）'
    })
    
    # 3. 处理 F 列（末次月经）- 去除时间点，只保留日期部分
    if '末次月经' in male_data.columns:
        def remove_time_from_date(date_str):
            if pd.isna(date_str) or str(date_str).strip() in ['', ' ', 'nan', 'NaN', 'None', '#']:
                return '未知'
            
            date_str = str(date_str).strip()
            
            # 处理包含时间的情况（如 "2023/2/1 0:00" 或 "2023-02-01 12:30:00"）
            if ' ' in date_str:  # 有空格分隔日期和时间
                date_part = date_str.split(' ')[0]  # 取空格前的日期部分
                return date_part
            elif 'T' in date_str:  # ISO格式（如 "2023-02-01T12:30:00"）
                date_part = date_str.split('T')[0]
                return date_part
            else:  # 纯日期格式，直接返回
                return date_str
        
        # 应用处理函数
        male_data['末次月经'] = male_data['末次月经'].apply(remove_time_from_date)
        print("末次月经列已去除时间点，仅保留日期部分")
    
    # 4. 处理 H 列（检测日期）- 保持之前的处理逻辑
    if '检测日期' in male_data.columns:
        # 替换#符号为明确的"未知"
        male_data['检测日期'] = male_data['检测日期'].replace(
            ['#', '##', '###', '####', '', ' ', 'nan', 'NaN'], '未知'
        )
    
    # 5. 原有数值型数据处理逻辑（保持不变）
    # 转换孕周数据为小数周
    def convert_gestational_week(week_str):
        if pd.isna(week_str) or str(week_str).strip() in ['', ' ', '未知']:
            return np.nan
        if isinstance(week_str, (int, float)):
            return float(week_str)
        week_str = str(week_str).strip()
        if 'w+' in week_str:
            parts = week_str.split('w+')
            weeks = int(parts[0]) if parts[0].isdigit() else 0
            days_part = parts[1].replace('d', '')
            days = int(days_part) if days_part.isdigit() else 0
            return weeks + days / 7
        elif 'w' in week_str:
            weeks_str = week_str.replace('w', '')
            return int(weeks_str) if weeks_str.isdigit() else np.nan
        elif week_str.replace('.', '').isdigit():
            return float(week_str)
        elif '周' in week_str:
            if '天' in week_str:
                parts = week_str.split('周')
                weeks = int(parts[0]) if parts[0].isdigit() else 0
                days_str = parts[1].replace('天', '')
                days = int(days_str) if days_str.isdigit() else 0
                return weeks + days / 7
            else:
                return int(week_str.replace('周', '')) if week_str.replace('周', '').isdigit() else np.nan
        else:
            return np.nan
    male_data['检测孕周(处理后)'] = male_data['检测孕周(处理后)'].apply(convert_gestational_week)
    initial_count = len(male_data)
    male_data = male_data[male_data['检测孕周(处理后)'].notna()]
    print(f"删除了 {initial_count - len(male_data)} 行孕周数据转换失败的行")
    
    # 过滤孕周范围 (10-25周)
    initial_count = len(male_data)
    male_data = male_data[(male_data['检测孕周(处理后)'] >= 10) & (male_data['检测孕周(处理后)'] <= 25)]
    print(f"删除了 {initial_count - len(male_data)} 行孕周不在10-25周范围内的行")
    
    # 处理BMI数据
    male_data['孕妇BMI（处理后）'] = pd.to_numeric(male_data['孕妇BMI（处理后）'], errors='coerce')
    initial_count = len(male_data)
    male_data = male_data[male_data['孕妇BMI（处理后）'].notna()]
    print(f"删除了 {initial_count - len(male_data)} 行BMI缺失的行")
    
    initial_count = len(male_data)
    male_data = male_data[(male_data['孕妇BMI（处理后）'] >= 15) & (male_data['孕妇BMI（处理后）'] <= 40)]
    print(f"删除了 {initial_count - len(male_data)} 行BMI不在合理范围(15-40)的行")
    
    # 处理Y染色体浓度数据
    male_data['Y染色体浓度（处理后）'] = pd.to_numeric(male_data['Y染色体浓度（处理后）'], errors='coerce')
    initial_count = len(male_data)
    male_data = male_data[male_data['Y染色体浓度（处理后）'].notna()]
    print(f"删除了 {initial_count - len(male_data)} 行Y浓度缺失的行")
    
    # 新增Y染色体浓度>=0.4的约束，同时保留原有的<=100约束
    initial_count = len(male_data)
    male_data = male_data[(male_data['Y染色体浓度（处理后）'] >= 0.04) & (male_data['Y染色体浓度（处理后）'] <= 1)]
    print(f"删除了 {initial_count - len(male_data)} 行Y浓度不在合理范围(0.04-1)的行")
    
    # 处理参考基因组比对比例（M列）
    male_data['在参考基因组上比对的比例'] = pd.to_numeric(male_data['在参考基因组上比对的比例'], errors='coerce')
    initial_count = len(male_data)
    male_data = male_data[male_data['在参考基因组上比对的比例'] >= 0.7]
    print(f"删除了 {initial_count - len(male_data)} 行在参考基因组上比对的比例<0.7的行")
    
    # 处理GC含量（P列）
    def process_gc_content(value):
        if pd.isna(value) or str(value).strip() in ['', ' ', '未知']:
            return np.nan
        if isinstance(value, str) and '%' in value:
            return float(value.replace('%', '')) / 100
        return float(value) if pd.to_numeric(value, errors='coerce') is not np.nan else np.nan
    male_data['GC含量'] = male_data['GC含量'].apply(process_gc_content)
    initial_count = len(male_data)
    male_data = male_data[(male_data['GC含量'] >= 0.4) & (male_data['GC含量'] <= 0.6)]
    print(f"删除了 {initial_count - len(male_data)} 行GC含量不在40%-60%范围内的行")
    
    # 最终数据整理
    male_data.reset_index(drop=True, inplace=True)
    
    return male_data

# 执行预处理
processed_data = preprocess_male_data('附件.xlsx')

# 保存为Excel并设置单元格格式
output_file = '处理后数据.xlsx'
processed_data.to_excel(output_file, index=False)

# 使用openpyxl调整单元格格式
wb = load_workbook(output_file)
ws = wb.active

# 设置末次月经列和检测日期列为文本格式，调整列宽
if '末次月经' in processed_data.columns:
    last_menstrual_col = processed_data.columns.get_loc('末次月经') + 1
    ws.column_dimensions[chr(64 + last_menstrual_col)].width = 15
    for cell in ws.iter_cols(min_col=last_menstrual_col, max_col=last_menstrual_col):
        for c in cell:
            c.number_format = '@'  # 文本格式

if '检测日期' in processed_data.columns:
    test_date_col = processed_data.columns.get_loc('检测日期') + 1
    ws.column_dimensions[chr(64 + test_date_col)].width = 15
    for cell in ws.iter_cols(min_col=test_date_col, max_col=test_date_col):
        for c in cell:
            c.number_format = '@'  # 文本格式

wb.save(output_file)
print(f"处理后的数据已保存为 '{output_file}'")

# 验证末次月经列处理结果
if '末次月经' in processed_data.columns:
    print("\n末次月经列处理后前10行数据:")
    print(processed_data['末次月经'].head(10).tolist())
